home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / Zoners Half-Life Tools / netvis / packet.h < prev    next >
C/C++ Source or Header  |  2001-04-25  |  27KB  |  1,063 lines

  1. #ifndef PACKET_H__
  2. #define    PACKET_H__
  3.  
  4. #ifdef HAVE_CONFIG_H
  5. #include "config.h"
  6. #endif
  7.  
  8. #include "basictypes.h"
  9. #include "hlassert.h"
  10. #include "vis.h"
  11.  
  12. #define NETVIS_PROTOCOL_VERSION    2042
  13.  
  14. #define MAX_PACKET_SIZE           65000
  15.  
  16. #define PORTAL_ARRAY_MAX_SIZE    128000
  17. #define UNINITIALIZED_PORTAL_INDEX   -1
  18. #define WAITING_FOR_PORTAL_INDEX     -2
  19. #define    NO_PORTAL_INDEX              -3
  20.  
  21. #define VARIABLE_LENGTH_PACKET         -1
  22.  
  23. // WORK_QUEUE_SIZE must be even for byte packing resons (8 byte alignment on structures)
  24. #define WORK_QUEUE_SIZE               8
  25.  
  26. #ifdef __cplusplus
  27.  
  28. #if _MSC_VER >= 1000
  29. #pragma once
  30. #endif // _MSC_VER >= 1000
  31.  
  32. #include <iostream>
  33.  
  34. #include "EndianMath.h"
  35.  
  36. class NetvisSession;
  37.  
  38. class basePacket
  39. {
  40. protected: // data
  41.     UINT32          header;
  42.     UINT32          pad;
  43.  
  44. public:    
  45.     enum PACKETtypes
  46.     {
  47.         VIS_PACKET_NULL,
  48.  
  49.         VIS_PACKET_LOGIN,            // Never change this id (it breaks graceful protocol negotiation)
  50.         VIS_PACKET_LOGIN_NAK,        // Never change this id (it breaks graceful protocol negotiation)
  51.         VIS_PACKET_LOGIN_ACK,        // Never change this id (it breaks graceful protocol negotiation)
  52.  
  53.         VIS_PACKET_WANT_BSP_DATA,    // Requests download of .bsp file image
  54.         VIS_PACKET_BSP_DATA_NAK,     // Server not ready, try again later
  55.         VIS_PACKET_BSP_DATA,         // .bsp image download
  56.         VIS_PACKET_BSP_NAME,         // .bsp filename on server (for informational purposes on client)
  57.  
  58.         VIS_PACKET_WANT_PRT_DATA,    // Requests download of .prt file image
  59.         VIS_PACKET_PRT_DATA_NAK,     // Server not ready, try again later
  60.         VIS_PACKET_PRT_DATA,         // .prt image download
  61.  
  62.         VIS_PACKET_WANT_MIGHTSEE_DATA,  // Requests download of baseportalvis's calculated mightsee & nummightsee data
  63.         VIS_PACKET_MIGHTSEE_DATA_NAK,   // Server is still crunching BasePortalVis, try again shortly
  64.         VIS_PACKET_MIGHTSEE_DATA,       // One of (many) packets containing baseportalvis mightsee & nummightsee data
  65.  
  66.         VIS_PACKET_LEAFTHREAD,       // Tells server client BasePortalVis has completed and is awaiting work
  67.         VIS_PACKET_LEAFTHREAD_ACK,   // Tells client LeafThread work is ready for request
  68.         VIS_PACKET_LEAFTHREAD_NAK,   // Tells client server is not ready to parcel out LeafThread work yet
  69.  
  70.         VIS_PACKET_WANT_FULL_SYNC,   // Tells server that the client wants a sync
  71.         VIS_PACKET_DONE_PORTAL,         // Gives server a completed work packet
  72.         VIS_PACKET_SYNC_PORTAL,      // Internal packet for SYNC_PORTAL_CLUSTER
  73.         VIS_PACKET_SYNC_PORTAL_CLUSTER,  // Multiple IS_SYNC_PORTAL packets embedded in a single packet, client to server sync up of work completed by all the other clients
  74.  
  75.         VIS_PACKET_GOING_DOWN        // Tells remote system connection is going to be terminated
  76.     };
  77.  
  78. public: // static methods
  79.     static  INT getPacketSizeByType(INT type);
  80.     static void HandleIncomingPacket(basePacket* packet, NetvisSession* socket);
  81.     static void DroppedClientForPortalIndex(long clientid, long index);
  82.     
  83. public: // construction
  84.     basePacket(UINT8 type)
  85.     {
  86.         setType(type);
  87.         setFiller(0);
  88.         INT size = getPacketSizeByType(type);
  89.         if (size != VARIABLE_LENGTH_PACKET)
  90.         {
  91.             setSize((UINT16)size);
  92.         }
  93.         else
  94.         {
  95.             size = 0;
  96.         }
  97.     }
  98.     
  99. public: // methods
  100.     void setType(UINT8 type)
  101.     {
  102.         UINT8* pHeader = reinterpret_cast<UINT8*>(&header);
  103.         pHeader[0] = type;
  104.     }
  105.     void setFiller(UINT8 filler)
  106.     {
  107.         UINT8* pHeader = reinterpret_cast<UINT8*>(&header);
  108.         pHeader[1] = filler;
  109.     }
  110.     void setSize(UINT16 size)
  111.     {
  112.         UINT16* pHeader = reinterpret_cast<UINT16*>(&header);
  113. #ifdef __LITTLE_ENDIAN__
  114.         pHeader[1] = size;
  115. #endif
  116. #ifdef __BIG_ENDIAN__
  117.         pHeader[1] = Endian::Flip(size);
  118. #endif
  119.     }
  120.  
  121.     UINT8 getType() const
  122.     { 
  123.         const UINT8* pHeader = reinterpret_cast<const UINT8*>(&header);
  124.         return pHeader[0];
  125.     }
  126.     UINT8 getFiller() const
  127.     { 
  128.         const UINT8* pHeader = reinterpret_cast<const UINT8*>(&header);
  129.         return pHeader[1];
  130.     }
  131.     UINT16 getSize() const
  132.     {
  133.         const UINT16* pHeader = reinterpret_cast<const UINT16*>(&header);
  134. #ifdef __LITTLE_ENDIAN__
  135.         return pHeader[1];
  136. #endif
  137. #ifdef __BIG_ENDIAN__
  138.         return Endian::Flip(pHeader[1]);
  139. #endif
  140.     }
  141.     bool validate() const
  142.     { 
  143.         int size = getPacketSizeByType(getType());
  144.         if (size != 0)
  145.         {
  146.             if (size == getSize())
  147.             {
  148.                 return true;
  149.             }
  150.             if (size == VARIABLE_LENGTH_PACKET)
  151.             {
  152.                 return true;
  153.             }
  154.         }
  155.         return false;
  156.     }
  157. };
  158.  
  159.  
  160.  
  161. class fixedPacket : public basePacket
  162. {
  163. public: // construction
  164.     fixedPacket(UINT8 type) : basePacket(type) {}
  165. public: // methods
  166. };
  167.  
  168.  
  169.  
  170. class varPacket : public basePacket
  171. {
  172. public: // construction
  173.     varPacket(UINT8 type) : basePacket(type) {}
  174. };
  175.  
  176.  
  177.  
  178. class VIS_PACKET : public fixedPacket
  179. {
  180. public: // data
  181.     CHAR            data[MAX_PACKET_SIZE - sizeof(fixedPacket)];
  182. public: // construction
  183.     VIS_PACKET() : fixedPacket(VIS_PACKET_NULL) {}
  184. };
  185.  
  186.  
  187.  
  188. class GOING_DOWN : public fixedPacket
  189. {
  190. public: // construction
  191.     GOING_DOWN() : fixedPacket(VIS_PACKET_GOING_DOWN) {}
  192. };
  193.  
  194.  
  195.  
  196. class WANT_FULL_SYNC : public fixedPacket
  197. {
  198. public: // construction
  199.     WANT_FULL_SYNC() : fixedPacket(VIS_PACKET_WANT_FULL_SYNC) {}
  200. };
  201.  
  202.  
  203.  
  204. class VIS_DONE_PORTAL : public varPacket
  205. {    // ATTN: This is a variable-length packet.  Changing this structure requires fixing up the ::Send code, as well as the getPacketSizeByType method)
  206. protected: // data
  207.     INT32           portalindex;
  208.     INT32           numcansee;
  209. public:
  210.     CHAR            data[4000];
  211. public: // construction
  212.     VIS_DONE_PORTAL() : varPacket(VIS_PACKET_DONE_PORTAL) { setSize(myoffsetof(VIS_DONE_PORTAL, data) + g_bitbytes); }
  213. #ifdef __LITTLE_ENDIAN__
  214.     INT32 getPortalIndex() const
  215.     {
  216.         return portalindex;
  217.     }
  218.     void setPortalIndex(INT32 val)
  219.     {
  220.         portalindex = val;
  221.     }
  222.     INT32 getNumCanSee() const
  223.     {
  224.         return numcansee;
  225.     }
  226.     void setNumCanSee(INT32 val)
  227.     {
  228.         numcansee = val;
  229.     }
  230. #endif
  231. #ifdef __BIG_ENDIAN__
  232.     INT32 getPortalIndex() const
  233.     {
  234.         return Endian::Flip(portalindex);
  235.     }
  236.     void setPortalIndex(INT32 val)
  237.     {
  238.         portalindex = Endian::Flip(val);
  239.     }
  240.     INT32 getNumCanSee() const
  241.     {
  242.         return Endian::Flip(numcansee);
  243.     }
  244.     void setNumCanSee(INT32 val)
  245.     {
  246.         numcansee = Endian::Flip(val);
  247.     }
  248. #endif
  249. };
  250.  
  251.  
  252.  
  253. class VIS_SYNC_PORTAL : public varPacket
  254. {    // ATTN: This is a variable-length packet.  Changing this structure requires fixing up the ::Send code, as well as the getPacketSizeByType method)
  255. protected: // data
  256.     INT32           portalindex;
  257.     INT32           numcansee;
  258.     INT32           fromclient; // which client this packet originated from
  259.     INT32           pad2;
  260. public:
  261.     CHAR            data[4000];
  262. public: // construction
  263.     VIS_SYNC_PORTAL() : varPacket(VIS_PACKET_SYNC_PORTAL) { setSize(myoffsetof(VIS_SYNC_PORTAL, data) + g_bitbytes); }
  264. #ifdef __LITTLE_ENDIAN__
  265.     INT32 getPortalIndex() const
  266.     {
  267.         return portalindex;
  268.     }
  269.     void setPortalIndex(INT32 val)
  270.     {
  271.         portalindex = val;
  272.     }
  273.     INT32 getNumCanSee() const
  274.     {
  275.         return numcansee;
  276.     }
  277.     void setNumCanSee(INT32 val)
  278.     {
  279.         numcansee = val;
  280.     }
  281.     INT32 getFromClient() const
  282.     {
  283.         return fromclient;
  284.     }
  285.     void setFromClient(INT32 val)
  286.     {
  287.         fromclient = val;
  288.     }
  289. #endif
  290. #ifdef __BIG_ENDIAN__
  291.     INT32 getPortalIndex() const
  292.     {
  293.         return Endian::Flip(portalindex);
  294.     }
  295.     void setPortalIndex(INT32 val)
  296.     {
  297.         portalindex = Endian::Flip(val);
  298.     }
  299.     INT32 getNumCanSee() const
  300.     {
  301.         return Endian::Flip(numcansee);
  302.     }
  303.     void setNumCanSee(INT32 val)
  304.     {
  305.         numcansee = Endian::Flip(val);
  306.     }
  307.     INT32 getFromClient() const
  308.     {
  309.         return Endia::Flip(fromclient);
  310.     }
  311.     void setFromClient(INT32 val)
  312.     {
  313.         fromclient = Endian::Flip(val);
  314.     }
  315. #endif
  316. };
  317.  
  318.  
  319.  
  320. class VIS_SYNC_PORTAL_CLUSTER : public varPacket
  321. {    // ATTN: This is a variable-length packet.  Changing this structure requires fixing up the ::Send code, as well as the getPacketSizeByType method)
  322. protected: // data
  323.     INT32           index[WORK_QUEUE_SIZE];  // >= 0 signifies this is a DONE sync, and to process this index
  324.     INT32           more_to_sync;   // > 0 signifies there is more to sync, and a sync request should be fired off, 31 bits are available here if you really need them
  325.     INT32           server_total;   // g_PortalArrayIndex of the server
  326.     INT32           subpacket_count;          // number of subpackets
  327. public:
  328.     CHAR            data[MAX_PACKET_SIZE - sizeof(varPacket) - (sizeof(INT32) * (WORK_QUEUE_SIZE+2))];    // data must be the last structure (unless the use of offsetof is changed to work it out)
  329. public: // construction
  330.     VIS_SYNC_PORTAL_CLUSTER() : varPacket(VIS_PACKET_SYNC_PORTAL_CLUSTER) 
  331.         { 
  332.             hlassert(sizeof(VIS_SYNC_PORTAL_CLUSTER) <= 65535);
  333.             setSize(myoffsetof(VIS_SYNC_PORTAL_CLUSTER, data));
  334.             setSubpacketCount(0);
  335.             for (int i = 0; i < WORK_QUEUE_SIZE; i++)
  336.             {
  337.                 index[i] = UNINITIALIZED_PORTAL_INDEX;
  338.             }
  339.             more_to_sync = false; 
  340.         }
  341. public: // methods
  342.     bool addSubpacket(VIS_SYNC_PORTAL* subpacket)
  343.     {
  344.         unsigned size = subpacket->getSize();
  345.         hlassert(size == getPacketSizeByType(VIS_PACKET_SYNC_PORTAL));
  346.         if ((getSize() + size) < sizeof(VIS_SYNC_PORTAL_CLUSTER))
  347.         {
  348.             char* pDataDest = reinterpret_cast<char*>(this) + getSize();
  349.             setSubpacketCount(getSubpacketCount() + 1);
  350.             setSize((UINT16) (getSize()+ size));
  351.             memcpy(pDataDest, subpacket, size);
  352.             return true;
  353.         }
  354.         return false;
  355.     }
  356.     VIS_SYNC_PORTAL* getSubpacket(UINT32 index)
  357.     {
  358.         hlassert(index < getSubpacketCount());
  359.         int size = getPacketSizeByType(VIS_PACKET_SYNC_PORTAL);
  360.         int offset = size * index;
  361.         hlassert(offset < getSize());   // rough cut, should never happen (packet header actually offsets this abit but its a fatal error either way)
  362.         if (offset > getSize())
  363.         {
  364.             return NULL;
  365.         }
  366.         return reinterpret_cast<VIS_SYNC_PORTAL*>(data + offset);
  367.     }
  368. #ifdef __LITTLE_ENDIAN__
  369.     INT32 getWork(int offset) const
  370.     {
  371.         return index[offset];
  372.     }
  373.     void setWork(INT32 val, int offset)
  374.     {
  375.         index[offset] = val;
  376.     }
  377.     INT32 getSubpacketCount() const
  378.     {
  379.         return subpacket_count;
  380.     }
  381.     void setSubpacketCount(INT32 val)
  382.     {
  383.         subpacket_count = val;
  384.     }
  385.     INT32 getMoreToSync() const
  386.     {
  387.         return more_to_sync;
  388.     }
  389.     void setMoreToSync(INT32 val)
  390.     {
  391.         more_to_sync = val;
  392.     }
  393.     INT32 getServerIndex() const
  394.     {
  395.         return server_total;
  396.     }
  397.     void setServerIndex(INT32 val)
  398.     {
  399.         server_total= val;
  400.     }
  401. #endif
  402. #ifdef __BIG_ENDIAN__
  403.     INT32 getWork(int offset) const
  404.     {
  405.         return Endian::Flip(index[offset]);
  406.     }
  407.     void setWork(INT32 val, int offset)
  408.     {
  409.         index[offset] = Endian::Flip(val);
  410.     }
  411.     INT32 getSubpacketCount() const
  412.     {
  413.         return Endian::Flip(subpacket_count);
  414.     }
  415.     void setSubpacketCount(INT32 val)
  416.     {
  417.         subpacket_count = Endian::Flip(val);
  418.     }
  419.     INT32 getMoreToSync() const
  420.     {
  421.         return Endian::Flip(more_to_sync);
  422.     }
  423.     void setMoreToSync(INT32 val)
  424.     {
  425.         more_to_sync = Endian::Flip(val);
  426.     }
  427.     INT32 getServerIndex() const
  428.     {
  429.         return Endian::Flip(server_total);
  430.     }
  431.     void setServerIndex(INT32 val)
  432.     {
  433.         server_total = Endian::Flip(val);
  434.     }
  435. #endif
  436. };
  437.  
  438.  
  439.  
  440. // Never change this packet header structure (it breaks graceful protocol negotiation)
  441. class VIS_LOGIN : public fixedPacket
  442. {
  443. public: // data
  444.     CHAR            hostname[128];
  445.     UINT32          protocol_version;
  446. public: // construction
  447.     VIS_LOGIN() : fixedPacket(VIS_PACKET_LOGIN) {setProtocolVersion(NETVIS_PROTOCOL_VERSION);}
  448. #ifdef __LITTLE_ENDIAN__
  449.     UINT32 getProtocolVersion() const
  450.     {
  451.         return protocol_version;
  452.     }
  453.     void setProtocolVersion(UINT32 val)
  454.     {
  455.         protocol_version = val;
  456.     }
  457. #endif
  458. #ifdef __BIG_ENDIAN__
  459.     UINT32 getProtocolVersion() const
  460.     {
  461.         return Endian::Flip(protocol_version);
  462.     }
  463.     void setProtocolVersion(UINT32 val)
  464.     {
  465.         protocol_version = Endian::Flip(val);
  466.     }
  467. #endif
  468. };
  469.  
  470.  
  471. // Never change this packet header structure (it breaks graceful protocol negotiation)
  472. class VIS_LOGIN_NAK : public fixedPacket
  473. {
  474. public: // data
  475.     UINT32          protocol_version;
  476. public: // construction
  477.     VIS_LOGIN_NAK() : fixedPacket(VIS_PACKET_LOGIN_NAK) {setProtocolVersion(NETVIS_PROTOCOL_VERSION);}
  478. #ifdef __LITTLE_ENDIAN__
  479.     UINT32 getProtocolVersion() const
  480.     {
  481.         return protocol_version;
  482.     }
  483.     void setProtocolVersion(UINT32 val)
  484.     {
  485.         protocol_version = val;
  486.     }
  487. #endif
  488. #ifdef __BIG_ENDIAN__
  489.     UINT32 getProtocolVersion() const
  490.     {
  491.         return Endian::Flip(protocol_version);
  492.     }
  493.     void setProtocolVersion(UINT32 val)
  494.     {
  495.         protocol_version = Endian::Flip(val);
  496.     }
  497. #endif
  498. };
  499.  
  500. #define flagFullvis (1 << 0)
  501.  
  502. // Never change this packet header structure (it breaks graceful protocol negotiation)
  503. class VIS_LOGIN_ACK : public fixedPacket
  504. {
  505. protected: // data
  506.     UINT32            clientid;
  507.     UINT32          flags;
  508. public: // construction
  509.     VIS_LOGIN_ACK() : fixedPacket(VIS_PACKET_LOGIN_ACK) {}
  510. #ifdef __LITTLE_ENDIAN__
  511.     UINT32 getClientId() const
  512.     {
  513.         return clientid;
  514.     }
  515.     void setClientId(UINT32 val)
  516.     {
  517.         clientid = val;
  518.     }
  519.     bool getFullvis() const
  520.     {
  521.         return flags & flagFullvis;
  522.     }
  523.     void setFullvis(bool on)
  524.     {
  525.         if (on)
  526.         {
  527.             flags |= flagFullvis;
  528.         }
  529.         else
  530.         {
  531.             flags &= ~flagFullvis;
  532.         }
  533.     }
  534. #endif
  535. #ifdef __BIG_ENDIAN__
  536.     UINT32 getClientId() const
  537.     {
  538.         return Endian::Flip(clientid);
  539.     }
  540.     void setClientId(UINT32 val)
  541.     {
  542.         clientid = Endian::Flip(val);
  543.     }
  544.     bool getFullvis() const
  545.     {
  546.         UINT32 tmp = Endian::Flip(flags);
  547.         return tmp & flagFullvis;
  548.     }
  549.     void setFullvis(bool on)
  550.     {
  551.         UINT32 tmp = Endian::Flip(flags);
  552.         if (on)
  553.         {
  554.             tmp |= flagFullvis
  555.         }
  556.         else
  557.         {
  558.             tmp &= ~flagFullvis;
  559.         }
  560.         flags = Endian::Flip(tmp);
  561.     }
  562. #endif
  563. };
  564.  
  565.  
  566.  
  567. //
  568. // Packets to download BSP data from server to client
  569. //
  570.  
  571. class VIS_WANT_BSP_DATA : public fixedPacket
  572. {
  573. public: // construction
  574.     VIS_WANT_BSP_DATA() : fixedPacket(VIS_PACKET_WANT_BSP_DATA) {}
  575. };
  576.  
  577.  
  578. class VIS_BSP_DATA_NAK : public fixedPacket
  579. {
  580. public: // construction
  581.     VIS_BSP_DATA_NAK() : fixedPacket(VIS_PACKET_BSP_DATA_NAK) {}
  582. };
  583.  
  584. class VIS_BSP_NAME : public fixedPacket
  585. {
  586. protected:
  587.     CHAR            bspname[512];
  588. public: // construction
  589.     VIS_BSP_NAME(const char* const name) : fixedPacket(VIS_PACKET_BSP_NAME) 
  590.     {
  591.         setName(name);
  592.     }
  593. public:
  594.     const char* getName() const
  595.     {
  596.         return bspname;
  597.     }
  598.     void setName(const char* const name)
  599.     {
  600.         safe_strncpy(bspname, name, sizeof(bspname));
  601.     }
  602. };
  603.  
  604. #define VIS_BSP_DATA_MAX_SIZE  (1024*1024*5)
  605. #define VIS_PRT_DATA_MAX_SIZE  (1024*1024*1)
  606.  
  607. class VIS_BSP_DATA : public varPacket
  608. {
  609. protected: // data
  610.     UINT32          compressed_size;        // Total size of image in compressed bytes
  611.     UINT32          uncompressed_size;      // Total size of image in uncompressed bytes
  612.     UINT32          fragment_size;
  613.     UINT32          offset;
  614. public:
  615.     CHAR            data[MAX_PACKET_SIZE - sizeof(varPacket) - (sizeof(UINT32) * 4)];  // data must be the last structure (unless the use of offsetof is changed to work it out)
  616. public: // construction
  617.     VIS_BSP_DATA() : varPacket(VIS_PACKET_BSP_DATA) { setSize(sizeof(VIS_BSP_DATA)); }
  618.     bool myValidate(void)   // Since we can't use virtual functions in network protocol packets, cant use validate()
  619.     {
  620.         hlassert(uncompressed_size <= VIS_BSP_DATA_MAX_SIZE);
  621.         if (uncompressed_size > VIS_BSP_DATA_MAX_SIZE)
  622.         {
  623.             return false;
  624.         }
  625.         hlassert(fragment_size <= sizeof(data));
  626.         if (fragment_size > sizeof(data))
  627.         {
  628.             return false;
  629.         }
  630.         hlassert((offset + fragment_size) <= compressed_size);
  631.         if ((offset + fragment_size) > compressed_size)
  632.         {
  633.             return false;
  634.         }
  635.         return true;
  636.     }
  637. #ifdef __LITTLE_ENDIAN__
  638.     UINT32 getCompressedSize() const
  639.     {
  640.         return compressed_size;
  641.     }
  642.     void setCompressedSize(UINT32 val)
  643.     {
  644.         compressed_size = val;
  645.     }
  646.     UINT32 getUncompressedSize() const
  647.     {
  648.         return uncompressed_size;
  649.     }
  650.     void setUncompressedSize(UINT32 val)
  651.     {
  652.         uncompressed_size = val;
  653.     }
  654.     UINT32 getFragmentSize() const
  655.     {
  656.         return fragment_size;
  657.     }
  658.     void setFragmentSize(UINT32 val)
  659.     {
  660.         fragment_size = val;
  661.     }
  662.     UINT32 getOffset() const
  663.     {
  664.         return offset;
  665.     }
  666.     void setOffset(UINT32 val)
  667.     {
  668.         offset = val;
  669.     }
  670. #endif
  671. #ifdef __BIG_ENDIAN__
  672.     UINT32 getCompressedSize() const
  673.     {
  674.         return Endian::Flip(compressed_size);
  675.     }
  676.     void setCompressedSize(UINT32 val)
  677.     {
  678.         compressed_size = Endian::Flip(compressed_size);
  679.     }
  680.     UINT32 getUncompressedSize() const
  681.     {
  682.         return Endian::Flip(uncompressed_size);
  683.     }
  684.     void setUncompressedSize(UINT32 val)
  685.     {
  686.         uncompressed_size = Endian::Flip(uncompressed_size);
  687.     }
  688.     UINT32 getFragmentSize() const
  689.     {
  690.         return Endian::Flip(fragment_size);
  691.     }
  692.     void setFragmentSize(UINT32 val)
  693.     {
  694.         fragment_size = Endian::Flip(val);
  695.     }
  696.     UINT32 getOffset() const
  697.     {
  698.         return Endian::Flip(offset);
  699.     }
  700.     void setOffset(UINT32 val)
  701.     {
  702.         offset = Endian::Flip(val);
  703.     }
  704. #endif
  705. };
  706.  
  707.  
  708. //
  709. // Packets to download PRT data from server to client
  710. //
  711.  
  712.  
  713. class VIS_WANT_PRT_DATA : public fixedPacket
  714. {
  715. public: // construction
  716.     VIS_WANT_PRT_DATA() : fixedPacket(VIS_PACKET_WANT_PRT_DATA) {}
  717. };
  718.  
  719.  
  720. class VIS_PRT_DATA_NAK : public fixedPacket
  721. {
  722. public: // construction
  723.     VIS_PRT_DATA_NAK() : fixedPacket(VIS_PACKET_PRT_DATA_NAK) {}
  724. };
  725.  
  726.  
  727. class VIS_PRT_DATA : public varPacket
  728. {
  729. protected: // data
  730.     UINT32          compressed_size;        // Total size of image in compressed bytes
  731.     UINT32          uncompressed_size;      // Total size of image in uncompressed bytes
  732.     UINT32          fragment_size;
  733.     UINT32          offset;
  734. public:
  735.     CHAR            data[MAX_PACKET_SIZE - sizeof(varPacket) - (sizeof(UINT32) * 4)];  // data must be the last structure (unless the use of offsetof is changed to work it out)
  736. public: // construction
  737.     VIS_PRT_DATA() : varPacket(VIS_PACKET_PRT_DATA) { setSize(sizeof(VIS_PRT_DATA)); }
  738.     bool myValidate(void)   // Since we can't use virtual functions in network protocol packets, cant use validate()
  739.     {
  740.         if (uncompressed_size > VIS_PRT_DATA_MAX_SIZE)
  741.         {
  742.             return false;
  743.         }
  744.         if (fragment_size > sizeof(data))
  745.         {
  746.             return false;
  747.         }
  748.         if (offset + fragment_size > compressed_size)
  749.         {
  750.             return false;
  751.         }
  752.         return true;
  753.     }
  754. #ifdef __LITTLE_ENDIAN__
  755.     UINT32 getCompressedSize() const
  756.     {
  757.         return compressed_size;
  758.     }
  759.     void setCompressedSize(UINT32 val)
  760.     {
  761.         compressed_size = val;
  762.     }
  763.     UINT32 getUncompressedSize() const
  764.     {
  765.         return uncompressed_size;
  766.     }
  767.     void setUncompressedSize(UINT32 val)
  768.     {
  769.         uncompressed_size = val;
  770.     }
  771.     UINT32 getFragmentSize() const
  772.     {
  773.         return fragment_size;
  774.     }
  775.     void setFragmentSize(UINT32 val)
  776.     {
  777.         fragment_size = val;
  778.     }
  779.     UINT32 getOffset() const
  780.     {
  781.         return offset;
  782.     }
  783.     void setOffset(UINT32 val)
  784.     {
  785.         offset = val;
  786.     }
  787. #endif
  788. #ifdef __BIG_ENDIAN__
  789.     UINT32 getCompressedSize() const
  790.     {
  791.         return Endian::Flip(compressed_size);
  792.     }
  793.     void setCompressedSize(UINT32 val)
  794.     {
  795.         compressed_size = Endian::Flip(compressed_size);
  796.     }
  797.     UINT32 getUncompressedSize() const
  798.     {
  799.         return Endian::Flip(uncompressed_size);
  800.     }
  801.     void setUncompressedSize(UINT32 val)
  802.     {
  803.         uncompressed_size = Endian::Flip(uncompressed_size);
  804.     }
  805.     UINT32 getFragmentSize() const
  806.     {
  807.         return Endian::Flip(fragment_size);
  808.     }
  809.     void setFragmentSize(UINT32 val)
  810.     {
  811.         fragment_size = Endian::Flip(val);
  812.     }
  813.     UINT32 getOffset() const
  814.     {
  815.         return Endian::Flip(offset);
  816.     }
  817.     void setOffset(UINT32 val)
  818.     {
  819.         offset = Endian::Flip(val);
  820.     }
  821. #endif
  822. };
  823.  
  824.  
  825. //
  826. // Packets to sync up clients with server's version of BasePortalVis data
  827. //
  828.  
  829. class VIS_WANT_MIGHTSEE_DATA : public fixedPacket
  830. {
  831. public: // construction
  832.     VIS_WANT_MIGHTSEE_DATA() : fixedPacket(VIS_PACKET_WANT_MIGHTSEE_DATA) {}
  833. };
  834.  
  835.  
  836. class VIS_MIGHTSEE_DATA_NAK : public fixedPacket
  837. {
  838. public: // construction
  839.     VIS_MIGHTSEE_DATA_NAK() : fixedPacket(VIS_PACKET_MIGHTSEE_DATA_NAK) {}
  840. };
  841.  
  842. class VIS_MIGHTSEE_DATA : public varPacket
  843. {    // ATTN: This is a variable-length packet.  Changing this structure requires fixing up the ::Send code, as well as the getPacketSizeByType method)
  844. protected: // data
  845.     INT32           portalindex;
  846.     INT32           nummightsee;
  847. public:
  848.     CHAR            data[4000];
  849. public: // construction
  850.     VIS_MIGHTSEE_DATA() : varPacket(VIS_PACKET_MIGHTSEE_DATA) { setSize(myoffsetof(VIS_MIGHTSEE_DATA, data) + g_bitbytes); }
  851. #ifdef __LITTLE_ENDIAN__
  852.     INT32 getPortalIndex() const
  853.     {
  854.         return portalindex;
  855.     }
  856.     void setPortalIndex(INT32 val)
  857.     {
  858.         portalindex = val;
  859.     }
  860.     INT32 getNumMightSee() const
  861.     {
  862.         return nummightsee;
  863.     }
  864.     void setNumMightSee(INT32 val)
  865.     {
  866.         nummightsee = val;
  867.     }
  868. #endif
  869. #ifdef __BIG_ENDIAN__
  870.     INT32 getPortalIndex() const
  871.     {
  872.         return Endian::Flip(portalindex);
  873.     }
  874.     void setPortalIndex(INT32 val)
  875.     {
  876.         portalindex = Endian::Flip(val);
  877.     }
  878.     INT32 getNumMightSee() const
  879.     {
  880.         return Endian::Flip(nummightsee);
  881.     }
  882.     void setNumMightSee(INT32 val)
  883.     {
  884.         nummightsee = Endian::Flip(val);
  885.     }
  886. #endif
  887. };
  888.  
  889.  
  890.  
  891.  
  892. //
  893. //
  894. // Packets to negotiate start of real client work
  895. //
  896.  
  897.  
  898. class VIS_LEAFTHREAD : public fixedPacket
  899. {
  900. protected: // data
  901.     INT32           portalleafs;
  902.     INT32           numportals;
  903.     INT32           bitbytes;
  904.     INT32           pad2;
  905. public: // construction
  906.     VIS_LEAFTHREAD() : fixedPacket(VIS_PACKET_LEAFTHREAD) {}
  907. #ifdef __LITTLE_ENDIAN__
  908.     INT32 getPortalLeafs() const
  909.     {
  910.         return portalleafs;
  911.     }
  912.     void setPortalLeafs(INT32 val)
  913.     {
  914.         portalleafs = val;
  915.     }
  916.     INT32 getNumPortals() const
  917.     {
  918.         return numportals;
  919.     }
  920.     void setNumPortals(INT32 val)
  921.     {
  922.         numportals = val;
  923.     }
  924.     INT32 getBitBytes() const
  925.     {
  926.         return bitbytes;
  927.     }
  928.     void setBitBytes(INT32 val)
  929.     {
  930.         bitbytes = val;
  931.     }
  932. #endif
  933. #ifdef __BIG_ENDIAN__
  934.     INT32 getPortalLeafs() const
  935.     {
  936.         return Endian::Flip(portalleafs);
  937.     }
  938.     void setPortalLeafs(INT32 val)
  939.     {
  940.         portalleafs = Endian::Flip(val);
  941.     }
  942.     INT32 getNumPortals() const
  943.     {
  944.         return Endian::Flip(numportals);
  945.     }
  946.     void setNumPortals(INT32 val)
  947.     {
  948.         numportals = Endian::Flip(val);
  949.     }
  950.     INT32 getBitBytes() const
  951.     {
  952.         return Endian::Flip(bitbytes);
  953.     }
  954.     void setBitBytes(INT32 val)
  955.     {
  956.         bitbytes = Endian::Flip(val);
  957.     }
  958. #endif
  959. };
  960.  
  961.  
  962.  
  963. class VIS_LEAFTHREAD_ACK : public fixedPacket
  964. {
  965. public: // construction
  966.     VIS_LEAFTHREAD_ACK() : fixedPacket(VIS_PACKET_LEAFTHREAD_ACK) {}
  967. };
  968.  
  969.  
  970.  
  971. class VIS_LEAFTHREAD_NAK : public fixedPacket
  972. {
  973. protected: // data
  974.     INT32           portalleafs;
  975.     INT32           numportals;
  976.     INT32           bitbytes;
  977.     INT32           pad2;
  978. public: // construction
  979.     VIS_LEAFTHREAD_NAK() : fixedPacket(VIS_PACKET_LEAFTHREAD_NAK) {}
  980. #ifdef __LITTLE_ENDIAN__
  981.     UINT32 getPortalLeafs() const
  982.     {
  983.         return portalleafs;
  984.     }
  985.     void setPortalLeafs(INT32 val)
  986.     {
  987.         portalleafs = val;
  988.     }
  989.     UINT32 getNumPortals() const
  990.     {
  991.         return numportals;
  992.     }
  993.     void setNumPortals(INT32 val)
  994.     {
  995.         numportals = val;
  996.     }
  997.     UINT32 getBitBytes() const
  998.     {
  999.         return bitbytes;
  1000.     }
  1001.     void setBitBytes(INT32 val)
  1002.     {
  1003.         bitbytes = val;
  1004.     }
  1005. #endif
  1006. #ifdef __BIG_ENDIAN__
  1007.     UINT32 getPortalLeafs() const
  1008.     {
  1009.         return Endian::Flip(portalleafs);
  1010.     }
  1011.     void setPortalLeafs(INT32 val)
  1012.     {
  1013.         portalleafs = Endian::Flip(val);
  1014.     }
  1015.     UINT32 getNumPortals() const
  1016.     {
  1017.         return Endian::Flip(numportals);
  1018.     }
  1019.     void setNumPortals(INT32 val)
  1020.     {
  1021.         numportals = Endian::Flip(val);
  1022.     }
  1023.     UINT32 getBitBytes() const
  1024.     {
  1025.         return Endian::Flip(bitbytes);
  1026.     }
  1027.     void setBitBytes(INT32 val)
  1028.     {
  1029.         bitbytes = Endian::Flip(val);
  1030.     }
  1031. #endif
  1032. };
  1033.  
  1034.  
  1035.  
  1036. #endif /* __cplusplus */
  1037.  
  1038.  
  1039. //
  1040. // Function Prototypes
  1041. //
  1042.  
  1043. extern void     Send_VIS_GOING_DOWN(NetvisSession* socket);
  1044. extern void     Send_VIS_WANT_FULL_SYNC_ping(void);
  1045. extern void     Send_VIS_WANT_FULL_SYNC(void);
  1046. extern void     Flag_VIS_DONE_PORTAL(long portalindex);
  1047. extern void     Send_VIS_DONE_PORTAL(long portalindex, portal_t* p);
  1048. extern void     Send_VIS_LOGIN(void);
  1049. extern void     Send_VIS_WANT_BSP_DATA(void);
  1050. extern void     Send_VIS_WANT_PRT_DATA(void);
  1051. extern void     Send_VIS_WANT_MIGHTSEE_DATA(void);
  1052. extern void     Send_VIS_LEAFTHREAD(long portalleafs, long numportals, long bitbytes);
  1053. extern void     Send_VIS_SYNC_PORTALs(NetvisSession* socket);
  1054.  
  1055. extern int      outOfWork(void);
  1056. extern int      stillOutOfWork(void);
  1057. extern int      needServerUpdate(void);
  1058. extern void     addWorkToClientQueue(long index);
  1059. extern long     getWorkFromClientQueue(void);
  1060.  
  1061.  
  1062. #endif // PACKET_H__
  1063.